package tuples;

import java.util.Comparator;

/**
 *
 * Fully Tested: No
 * Fully Documented: Yes
 * Created: 21-Dec-2011
 * Last Updated: 21-Dec-2011
 *
 * @param <T1> the type of the first element in the Pair
 * @param <T2> the type of the second element in the Pair
 * @author Shimu Wu
 */
public class Pair <T1, T2>{
    
    private final T1 ELEMENT1;
    private final T2 ELEMENT2;
    
    public Pair(T1 element1, T2 element2){
        this.ELEMENT1 = element1;
        this.ELEMENT2 = element2;
    }

    /**
     * @return the first element in the tuple
     */
    public T1 getFirst() {
        return ELEMENT1;
    }

    /**
     * @return the second element in the tuple
     */
    public T2 getSecond() {
        return ELEMENT2;
    }
    
    /**
     * Returns a Comparator that can be used to compare two pairs storing
     * T objects as its first element using the compareTo method of class T.
     * 
     * @param <T>
     * @param c
     * @return 
     */
    public static <T extends Comparable> Comparator<Pair<T, ?>> 
            getFirstComparator(Class<T> c) {
        return new Comparator<Pair<T, ?>>(){
            public int compare(Pair<T, ?> o1, Pair<T, ?> o2) {
                return o1.getFirst().compareTo(o2.getFirst());
            }
        };
    }
    
    /**
     * Returns a Comparator that can be used to compare two pairs storing
     * T objects as its second element using the compareTo method of class T.
     * 
     * @param <T>
     * @param c
     * @return 
     */
    public static <T extends Comparable> Comparator<Pair<?, T>> 
            getSecondComparator(Class<T> c) {
        return new Comparator<Pair<?, T>>(){

            public int compare(Pair<?, T> o1, Pair<?, T> o2) {
                return o1.getSecond().compareTo(o2.getSecond());
            }
        };
    }
    
    @Override
    public String toString(){
        return String.format("Pair: (%s, %s)", String.valueOf(ELEMENT1),
                String.valueOf(ELEMENT2));
    }

}
